﻿using System.Runtime.CompilerServices;
using Controller;
using NN = NNCore;

namespace GACore.ReversiGA
{
	public abstract class Tournament
	{
		protected Vector[] vectors;
		protected NN.Controller[] nnControllers;

		public Tournament(NN.Controller[] nnControllers)
		{
			this.nnControllers = nnControllers;
		}

		public virtual void PlayTournament(Vector[] vectors)
		{
			this.vectors = vectors;
		}

		protected void PlayGame(PlayerTypes playerType1, PlayerTypes playerType2, int id1, int id2)
		{
			NN.Controller nnController1 = id1 >= 0 ? nnControllers[id1] : null;
			NN.Controller nnController2 = id2 >= 0 ? nnControllers[id2] : null;
			ReversiController rController = new ReversiController(playerType1, playerType2, nnController1, nnController2, id1, id2, false);
			rController.GameEnded += rController_GameEnded;
			rController.StartGame();
		}

		protected void rController_GameEnded(object sender, GameEndedEventArgs e)
		{
			SetPoints(e);
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		protected void SetPoints(GameEndedEventArgs e)
		{
			if (e.Id1 >= 0)
			{
				vectors[e.Id1].Fitness.AddResult(e.Winner == 1, e.CountTokens1, e.CountTokens2, e.CountPossibleMoves1, e.CountPossibleMoves2, e.CountCorners1);
			}
			if (e.Id2 >= 0)
			{
				vectors[e.Id2].Fitness.AddResult(e.Winner == 2, e.CountTokens2, e.CountTokens1, e.CountPossibleMoves2, e.CountPossibleMoves1, e.CountCorners2);
			}
		}
	}
}
